import sys
import codecs

from amgineirc.model.amgine.engines.unspin import Unspin
from amgineirc.model.amgine.engines.spin import Spin
from amgineirc.model.amgine.engines.streams import *

class ClockWorks(object):
    """
    this is just a wrapper for Spin and Unspin
    """
    
    def __init__(self):
        pass

    # string to bytes - bytes to string
    
    def wind_string_to_bytes(self, b2b_rule, s, encodeString='utf-8'):
        """
        converts a string to a list of bytearrays.
        returns a list of bytearrays
        """
        iStream = StringReadStream(s, encodeString)
        # return a list of spun strings
        works = Spin(b2b_rule, iStream)
        spin_list = works.spin()
        return [bytearray(i) for i in spin_list]
    
    def unwind_string_from_bytes(self, b2b_rule, byte_array, decodeString='utf-8'):
        """
        converts bytes to a string.
        returns a decoded string
        """
        iStream = ByteReadStream(byte_array)
        works = Unspin(b2b_rule, iStream)
        unspin_list = works.unspin()
        # decode the strings to the original readable form
        decoder = codecs.getdecoder(decodeString)
        ba = bytearray(unspin_list)
        return decoder(ba)[0]
        # return [str(decoder(i)[0]) for i in baList]

    # bytes to bytes
    
    def wind_bytes_to_bytes(self, b2b_rule, byte_array):
        """
        winds a bytearray into another bytearray
        a is the readable string or array of readable strings
        the readable string encoding must be correctly represented by encodeString
        """
        iStream = ByteReadStream(byte_array)
        # return a list of spun strings
        works = Spin(b2b_rule, iStream)
        spin_list = works.spin()
        return [bytearray(i) for i in spin_list]

    def unwind_bytes_from_bytes(self, b2b_rule, byte_array):
        """
        unconverts bytes from bytes
        returns a single bytearray
        """
        iStream = ByteReadStream(byte_array)
        works = Unspin(b2b_rule, iStream)
        unspin_list = works.unspin()
        return bytearray(unspin_list)
        
    # bytes to ascii string
    
    def wind_bytes_to_ascii(self, b2a_rule, ba_list):
        """
        converts a bytearray to ascii characters.
        returns a list of ascii strings.
        """
        iStream = ByteReadStream(ba_list)
        works = Spin(b2a_rule, iStream)
        spin_list = works.spin()
        return [''.join(i) for i in spin_list]
    
    def unwind_bytes_from_ascii(self, b2a_rule, text):
        """
        unconverts ascii text wound using ClockWorks.wind to a bytearray
        returns a single bytearray
        """
        iStream = CharReadStream(text)
        works = Unspin(b2a_rule, iStream)
        unspin_list = works.unspin()
        return bytearray(unspin_list)
